﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace PlusPlusPaint.GUI
{
    class SketchControl : UserControl
    {
        private Image preview;
        private Image currentImage;
        private bool mousePressed = false;
        private bool toolLayerSet = false;
        private Tools.ISketchTool currentTool;
        public Tools.ISketchTool CurrentTool
        {
            get
            {
                return currentTool;
            }
            set
            {
                if (currentTool == value)
                    return;
                this.toolLayerSet = false;
                this.currentTool = value;
                this.currentTool.Preview = preview;
            }
        }
        public Layers.LayerManager LayerManager;

        #region events
        public event EventHandler ToolInvalid;
        #endregion
        
        public SketchControl(Layers.LayerManager lm)
        {
            this.LayerManager = lm;
            lm.Invalidated += (object sender, EventArgs ea) => this.Invalidate();
            this.BorderStyle = BorderStyle.Fixed3D;
            this.BackColor = Color.White;
            this.DoubleBuffered = true;
            this.Paint += this.handleDraw;
            this.Resize += this.handleResize;
            this.handleResize(this, EventArgs.Empty);

            this.MouseDown += (object sender, MouseEventArgs mea) =>
            {
                if (!this.toolLayerSet)
                    LayerManager.ApplyToolAtPoint(this.currentTool, mea.Location);
                this.mousePressed = true;
                this.CurrentTool.HandleMouseDown(mea);
            };
            this.MouseMove += (object sender, MouseEventArgs mea) =>
            {
                if (!this.mousePressed)
                    return;
                this.CurrentTool.HandleMouseDrag(mea);
                lm.Invalidate();
            };
            this.MouseUp += (object sender, MouseEventArgs mea) =>
            {
                this.mousePressed = false;
                this.CurrentTool.HandleMouseUp(mea);
                if (CurrentTool.Done && ToolInvalid != null)
                    ToolInvalid(this, EventArgs.Empty);
                lm.Invalidate();
            };
            this.KeyPress += (object sender, KeyPressEventArgs kpea) =>
            {
                CurrentTool.HandleKeyPressed(kpea);
            };
            this.LayerManager.Invalidated += (object o, EventArgs ea) =>
            {
                this.imageNoLongerValid();
            };
        }
        
        private void handleDraw(object o, PaintEventArgs pea)
        {
            pea.Graphics.DrawImage(currentImage, 0, 0);
            pea.Graphics.DrawImage(preview, 0, 0);
        }
        
        private void handleResize(object o, EventArgs ea)
        {
            this.preview = new Bitmap(Size.Width, Size.Height);
            if (this.CurrentTool != null)
                this.CurrentTool.Preview = preview;
            this.imageNoLongerValid();
            this.Invalidate();
        }

        private void imageNoLongerValid()
        {
            this.currentImage = LayerManager.GetVisualRepresentationWithDimensions(this.ClientSize);
        }
        
        public void Clear(object o, EventArgs ea)
        {
            LayerManager.Drop(); // Raises invalidate, so we don't need to.
        }
    }
}
